public class Test10 {
    static class WaitThread implements Runnable{
        Object flag = new Object();
        public WaitThread(Object flag) {
            this.flag = flag;
        }
        @Override
        public void run() {
            System.out.println("Wait1 开始");
            synchronized (flag){
                try {
                    flag.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Wait1 结束");
            }
        }
    }
    static class WaitThread2 implements Runnable{
        Object flag = new Object();
        public WaitThread2(Object flag) {
            this.flag = flag;
        }
        @Override
        public void run() {
            System.out.println("Wait2 开始");
            synchronized (flag){
                try {
                    flag.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Wait2 结束");
            }
        }
    }
    static class WaitThread3 implements Runnable{
        Object flag = new Object();
        public WaitThread3(Object flag) {
            this.flag = flag;
        }
        @Override
        public void run() {
            System.out.println("Wait3 开始");
            synchronized (flag){
                try {
                    flag.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Wait3 结束");
            }
        }
    }
    static class NotifyThread implements Runnable{
        Object flag = new Object();
        public NotifyThread(Object flag) {
            this.flag = flag;
        }
        @Override
        public void run() {
            synchronized (flag){
                //flag.notify();
                System.out.println("第一次唤醒");
                flag.notifyAll();
                System.out.println("第二次唤醒");
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Object object = new Object();
        Thread thread1 = new Thread(new WaitThread(object));
        Thread thread2 = new Thread(new WaitThread2(object));
        Thread thread3 = new Thread(new WaitThread3(object));
        Thread notify = new Thread(new NotifyThread(object));
        thread1.start();
        Thread.sleep(1000);
        thread2.start();
        Thread.sleep(1000);
        thread3.start();
        Thread.sleep(1000);
        notify.start();
    }
}
